<?php
/*

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	1. Redistributions of source code must retain the above copyright notice,
	this list of conditions and the following disclaimer.

	2. Redistributions in binary form must reproduce the above copyright
	notice, this list of conditions and the following disclaimer in the
	documentation and/or other materials provided with the distribution.

	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.
*/

##|+PRIV
##|*IDENT=page-diagnostics-packetcapture
##|*NAME=Diagnostics: Packet Capture page
##|*DESCR=Allow access to the 'Diagnostics: Packet Capture' page.
##|*MATCH=diag_packet_capture.php*
##|-PRIV


$pgtitle = array("系统工具", "抓包");
require_once("guiconfig.inc");
require_once("pfsense-utils.inc");

$fp = "/tmp/";
$fn = "packetcapture.cap";
$snaplen = 1500;//default packet length
$count = 100;//default number of packets to capture

if ($_POST) {
	$do_tcpdump = true;
	$host = $_POST['host'];
	$selectedif = $_POST['interface'];
	$count = $_POST['count'];
	$packetlength = $_POST['snaplen'];
	$port = $_POST['port'];
	$detail = $_POST['detail'];

	if ($_POST['dnsquery'])//if dns lookup is checked
	{
		$disabledns = "";
	}
	else //if dns lookup is unchecked
	{
		$disabledns = "-n";
	}

	if ($_POST['startbtn'] != "" )
	{
		$action = "Start";
		
	 	//delete previous packet capture if it exists
	 	if (file_exists($fp.$fn))
	 		unlink ($fp.$fn);

	}
	elseif ($_POST['stopbtn']!= "")
	{
		$action = "Stop";
		$processes_running = trim(shell_exec("ps axw -O pid= | grep tcpdump | grep $fn | grep -v pflog"));

		//explode processes into an array, (delimiter is new line)
		$processes_running_array = explode("\n", $processes_running);

		//kill each of the packetcapture processes
		foreach ($processes_running_array as $process)
		{
			$process_id_pos = strpos($process, ' ');
			$process_id = substr($process, 0, $process_id_pos);
			exec("kill $process_id");
		}

	}
	else //download file
	{
		$fs = filesize($fp.$fn);
		header("Content-Type: application/octet-stream");
        header("Content-Disposition: attachment; filename=$fn");
		header("Content-Length: $fs");
		readfile($fp.$fn);
	}
}
else
{
	$do_tcpdump = false;

}
$pgtitle = "系统工具：抓包";
include("head.inc"); ?>
<body link="#000000" vlink="#0000CC" alink="#0000CC">
<? include("fbegin.inc"); ?>
<div class="soft_cont_right_table">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
        <tr>
          <td>
			<form action="diag_packet_capture.php" method="post" name="iform" id="iform">
			  <table width="100%" border="0" cellpadding="6" cellspacing="0">
				<tr>
					<td colspan="2" valign="top" class="listtopic">抓包</td>
				</tr>	
               	<tr>
				  <td width="17%" valign="top" class="vncellreq">接口</td>
				  <td width="83%" class="vtable">
				<select name="interface">
                     <?php $interfaces = get_configured_interface_with_descr();
					  foreach ($interfaces as $iface => $ifacename): ?>
                      <option value="<?=$iface;?>" <?php if (!link_interface_to_bridge($iface) && $selectedif == $iface) echo "selected"; ?>>
                      <?php echo $ifacename;?>
                      </option>
                      <?php endforeach;?>
                    </select>
                    <br/>选择需要进行抓包的接口。
				  </td>
				</tr>
			    <tr>
				  <td width="17%" valign="top" class="vncellreq">主机地址</td>
				  <td width="83%" class="vtable">
                    <input name="host" type="text" class="formfld host" id="host" size="20" value="<?=htmlspecialchars($host);?>">
					<br/>地址可以是源地址或者目的地址。
					<br/>地址可以是域名或者IP地址。
					<br/>如果留空，所有的包都会被捕获。
					</td>
				</tr>
				<tr>
				  <td width="17%" valign="top" class="vncellreq">端口</td>
				  <td width="83%" class="vtable">
                    <input name="port" type="text" class="formfld unknown" id="port" size="5" value="<?=$port;?>">
					<br/>可以使源端口或者目的端口。
					<br/>如果不想使用端口过滤请留空。
					</td>
				</tr>
				<tr>
				  <td width="17%" valign="top" class="vncellreq">包长度</td>
				  <td width="83%" class="vtable">
                    <input name="snaplen" type="text" class="formfld unknown" id="snaplen" size="5" value="<?=$snaplen;?>">
					<br/>包长度是每个抓取的包将会保留的字节数。默认值是1500。
					<br/>该值需要和所选接口的MTU值相同。
					</td>
				</tr>
				<tr>
				  <td width="17%" valign="top" class="vncellreq">包个数</td>
				  <td width="83%" class="vtable">
                    <input name="count" type="text" class="formfld unknown" id="count" size="5" value="<?=$count;?>">
					<br/>抓包的个数。默认值是100。 <br/>输入0取消限制。
				</tr>
				<tr>
				  <td width="17%" valign="top" class="vncellreq">详细程度</td>
				  <td width="83%" class="vtable">
                    <select name="detail" type="text" class="formselect" id="detail" size="1">
						<option value="-q" <?php if ($detail == "-q") echo "selected"; ?>>普通</option>
						<option value="-v" <?php if ($detail == "-v") echo "selected"; ?>>中等</option>
						<option value="-vv" <?php if ($detail == "-vv") echo "selected"; ?>>高</option>
						<option value="-vv -e" <?php if ($detail == "-vv -e") echo "selected"; ?>>全部</option>
					</select>
					<br/>抓包信息的详细程度。<br/><b>注意：</b> 这个选项对下载的抓包记录无影响。
				</tr>
				<tr>
				  <td width="17%" valign="top" class="vncellreq">DNS反向解析</td>
				  <td width="83%" class="vtable">
					<input name="dnsquery" type="checkbox"<?php if($_POST['dnsquery']) echo " CHECKED"; ?>>
					<br/>选中这个选项会对所有的IP地址进行DNS反响解析。
					<br/><b>注意：</b>启用该选项进行大量抓包操作会对CPU有一定消耗。
					</td>
				</tr>
				<tr>
				  <td width="17%" valign="top">&nbsp;</td>
				  <td width="83%">
                    <?php

                    /*check to see if packet capture tcpdump is already running*/
					$processcheck = (trim(shell_exec("ps axw -O pid= | grep tcpdump | grep $fn | grep -v pflog")));
					
					$processisrunning = false;

					if ($processcheck != false)
						$processisrunning = true;
						
					if (($action == "Stop" or $action == "") and $processisrunning != true)
						echo "<input type=\"submit\" name=\"startbtn\" value=\"开始\">&nbsp;";
				  	else{
					  	echo "<input type=\"submit\" name=\"stopbtn\" value=\"停止\">&nbsp;";
				  	}
					if (file_exists($fp.$fn) and $processisrunning != true){
						echo "<input type=\"submit\" name=\"downloadbtn\" value=\"下载\">";
						echo "&nbsp;&nbsp;(抓包文件最后更新于：" . date("F jS, Y g:i:s a.", filemtime($fp.$fn)) . ")";
					}
					?>
				  </td>
				</tr>
				<tr>
				<td valign="top" colspan="2">
				<?php
				echo "<font face='terminal' size='2'>";
				if ($processisrunning == true)
						echo("<strong>正在抓包……</strong><br/>");
						
				if ($do_tcpdump) {					

					if ($port != "")
                    {
                       $searchport = "and port ".$port;
                       if($host <> "")                        
							$searchport = "and port ".$port;
						else
							$searchport = "port ".$port;
                    }
                    else
                    {
                        $searchport = "";
                    }

       				if ($host != "")
         	       {
             	       $searchhost = "host " . $host;
            	   }
             	   else
                	{
                       $searchhost = "";
             		}
             		if ($count != "0" )
             		{
             			 $searchcount = "-c " . $count;
             		}
             		else
             		{
             			$searchcount = "";
             		}

					$selectedif = convert_friendly_interface_to_real_interface_name($selectedif);
				
					
						
					if ($action == "Start")
					{
						echo("<strong>正在抓包……</strong><br/>");
					 	mwexec_bg ("/usr/sbin/tcpdump -i $selectedif $searchcount -s $packetlength -w $fp$fn $searchhost $searchport");
						}
					else  //action = stop
					{

						echo("<strong>停止抓包。<br/><br/>抓取的数据包：</strong><br/>");
						?>
						<textarea style="width:98%" name="code" rows="15" cols="66" wrap="off" readonly="readonly">
						<?php
						system ("/usr/sbin/tcpdump $disabledns $detail -r $fp$fn");?>
						</textarea><?php
					}
				}?>
				</td>
				</tr>
				<tr>

		</table>
</form>
</td></tr></table>
</div>
<?php include("fend.inc"); ?>
